/**
 * 
 */
package com.glela.platform.service.impl;
import java.net.URLEncoder;
import java.util.Date;

import javax.annotation.Resource;

import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.glela.api.sms.xinxi1.SendMsg;
import com.glela.cache.redis.RedisKeys;
import com.glela.cache.redis.RedisUtil;
import com.glela.common.model.sms.SMSVerifyCode;
import com.glela.common.model.sms.SMSVerifyCode.VerifyCodeType;
import com.glela.common.service.SMSService;
import com.glela.common.util.HttpUtil;
import com.glela.common.util.RandomNumberUtil;
import com.glela.common.util.RandomUtil;
import com.glela.common.util.SmsContents;
import com.glela.common.util.SmsContentsError;
import com.glela.common.util.StringUtil;
import com.glela.common.util.StringUtils;
import com.glela.constant.CodeTimeOutConstant;
import com.glela.constant.SmsConstant;
import com.glela.platform.mapper.CheckCodeMapper;
import com.glela.platform.mapper.OperationLogMapper;
import com.glela.platform.mapper.SCheckCodeMapper;
import com.glela.platform.mapper.UserMapper;
import com.glela.platform.model.CheckCode;
import com.glela.platform.model.OperationLog;
import com.glela.platform.model.SCheckCode;
import com.glela.platform.service.BaseRestrictionsService;
import com.glela.platform.service.SmsService;
import com.glela.platform.util.DateUtils;

/**
 * @author liujie
 */
@Service
public class SmsServiceImpl  implements SmsService
{
	Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);
    
	@Autowired
	private SMSService			smsService;
    @Resource
	private CheckCodeMapper checkCodeMapper;
    @Resource
	RedisUtil redisUtil;
    @Autowired
	UserMapper userMapper;
    @Autowired
   	private SCheckCodeMapper sCheckCodeMapper;
    
    @Autowired
	private BaseRestrictionsService  baseRestrictionsService;
    
    @Autowired
	private OperationLogMapper  operationLogMapper;

	@Override
	public boolean sendVerifyCodeSms(String mobile, Integer smsType, Integer sendMode) {
		if(sendMode==null){
			return false;
		}
		if(sendMode.equals(SmsConstant.MODE_TEXT)){
			return sendTextVerifyCodeSms(mobile,smsType);
		}else if(sendMode.equals(SmsConstant.MODE_VOICE)){
			return sendVoiceVerifyCodeSms(mobile,smsType);
		}
		return false;
	}

	@Override
	public boolean sendTextVerifyCodeSms(String mobile, Integer smsType) {
		String content = SmsConstant.content.getContentByType(smsType);
		String code = RandomNumberUtil.createRandowNumber();
		content = String.format(content, code);
		String sid = SendMsg.sendSms(mobile, content);
		if(sid.equals("")){
			return false;
		}
		return saveVerifyCodeRecord(sid,mobile,code,smsType);
	}

	@Override
	public boolean sendVoiceVerifyCodeSms(String mobile, Integer smsType) {
		String code = RandomNumberUtil.createRandowNumber();
		String sid = SendMsg.sendVoiceVerifyCode(mobile, code);
		if(sid.equals("")){
			return false;
		}
		return saveVerifyCodeRecord(sid,mobile,code,smsType);
	}
	
	@Override
	public boolean sendTextSms(String mobile,Integer smsType,String content){
		String sid = SendMsg.sendSms(mobile, content);
		if(sid.equals("")){
			return false;
		}
		return true;
	}
	
	@Override
	public boolean checkVerifyCode(String mobile, Integer smsType, String inputCode) {
		if(StringUtils.isEmpty(mobile) || smsType==null || StringUtils.isEmpty(inputCode)){
			return false;
		}
		String key = String.format(RedisKeys.VERIFY_CODE, mobile,smsType);
		String code = redisUtil.get(key);
		if(code==null || !code.equals(inputCode)){
			return false;
		}
		return true;
	}
	
    /**
     * 记录验证码信息，包括redis 和 数据库
     * @param sid
     * @param mobile
     * @param code
     * @param type
     * @return
     */
	private boolean saveVerifyCodeRecord(String sid,String mobile,String code,Integer type){
		//redis
		try{
			String key = String.format(RedisKeys.VERIFY_CODE, mobile,type);
			redisUtil.set(key, code);
			redisUtil.expire(key, SmsConstant.VERIFY_CODE_TIMEOUT);
		}catch(Exception e){
			logger.error("保存验证码redis记录异常：",e);
			return false;
		}
		
		//数据,发送异常也不影响用户验证
		try{
			CheckCode checkCode = new CheckCode();
			checkCode.setCode(code);
			checkCode.setType(type);
			checkCodeMapper.insert(checkCode);
		}catch(Exception e){
			logger.error("保存验证码发送记录异常：",e);
		}
		return true;
	}

	@Override
	public Integer getVoiceVerifyCodeStatus(String key) {
		if(StringUtils.isEmpty(key)){
			return 0;
		}
		try{
			Integer value = userMapper.selectSystemFlag(key);
			if(value == null){
				return 0;
			}
			return value;
		}catch(Exception e){
			logger.error("查询语音验证码开关状态异常：",e);
		}
		return 0;
	}

	@Override
	public void removeVerifyCode(String mobile, Integer smsType) {
		if(StringUtil.isEmpty(mobile) || smsType==null){
			return;
		}
		try{
			String key = String.format(RedisKeys.VERIFY_CODE, mobile,smsType);
			redisUtil.del(key);
		}catch(Exception e){
			logger.error("删除验证码redis记录异常：",e);
		}
	}

	@Override
	public boolean checkVerifyCode(String mobile, Integer smsType, String inputCode, boolean remove) {
		boolean rst = checkVerifyCode(mobile,smsType,inputCode);
		if(rst && remove){
			removeVerifyCode(mobile,smsType);
		}
		return rst;
	}

//	@Override
//	public boolean sendNumberVerifyCodeSms(String mobile, int smsType, String userId) {
////		String content = SmsConstant.content.getContentByType(smsType);
////		String code = RandomNumberUtil.createRandowNumber(6);
////		content = String.format(content, code);
////		String sid = SendMsg.sendSms(mobile, content);
////		if(sid.equals("")){
////			return false;
////		}
//		return saveVerifyCode(mobile,code,smsType,userId);
//	}
	/** 
	* @Title: saveVerifyCode 
	* @Description: 保存发送验证码的记录到数据库
	* @param @param sid
	* @param @param mobile
	* @param @param code
	* @param @param type
	* @param @param userId
	* @param @return    设定文件 
	* @return boolean    返回类型 
	* @throws 
	* @author zhangrenjie 
	* @date 2017年8月14日 下午1:40:14 
	*/
	private boolean saveVerifyCode(String mobile,String code,Integer type,String userId){
		try{
			SCheckCode checkCode = new SCheckCode();
			checkCode.setCode(code);
			checkCode.setMobile(mobile);
			checkCode.setType(new Byte(type.toString()));
			checkCode.setUserId(Long.parseLong(userId));
			checkCode.setStatus(new Byte("1"));
			sCheckCodeMapper.insertSelective(checkCode);
		}catch(Exception e){
			logger.error("保存验证码发送记录异常：",e);
		}
		return true;
	}

	@Override
	public int validateVerifyCode(String mobile, String type, String code) {
		SCheckCode  sCheckCode =  sCheckCodeMapper.selectLastOneByMobileAndType(mobile,type);
		if(null != sCheckCode ){
			long t = DateUtils.getNowDate(DateUtils.DATE_TIME_FORMAT).getTime() - sCheckCode.getCreateTime().getTime();
				if (CodeTimeOutConstant.timeoutThirty < t) {//超时
					sCheckCode.setStatus(new Byte("0"));
					sCheckCodeMapper.updateByPrimaryKeySelective(sCheckCode);
					return 2;
				}
				if (code.equals(sCheckCode.getCode())) {//验证通过
					sCheckCode.setStatus(new Byte("0"));
					sCheckCodeMapper.updateByPrimaryKeySelective(sCheckCode);
					return 1;
				}else {
					return 3;
				}
		}
		return 4;
	}

	@Override
	public boolean sendNumberVerifyCodeSms(String mobile, int smsType, String userId, String content) {
		try {
			String code=RandomUtil.getRandomNumber(6);
			content = String.format(content, code);
			/*String PostData = "userid=&account=98a33e&password=kn2t9xmhpz&mobile="+mobile+"&content="+content;
			String tr=SendSMS.send(PostData, "http://api.chanzor.com/send");*/
			
			String smsUrl = baseRestrictionsService.getBaseRestrictionsForCache("sendSms_url").getName();
			String account = baseRestrictionsService.getBaseRestrictionsForCache("sendSms_account").getName();
			String pwd = baseRestrictionsService.getBaseRestrictionsForCache("sendSms_pwd").getName();
			String msg = URLEncoder.encode(content, "UTF-8");
			SmsContents contents = new  SmsContents(account, pwd,mobile, msg);
			String codeJz = HttpUtil.doPost(contents.toString(),smsUrl, "application/x-www-form-urlencoded");
			String resultInfo = SmsContentsError.checkCode(codeJz);
			OperationLog log = new OperationLog();
			log.setObjId(Integer.parseInt(userId));
			log.setObjName(userId);
			log.setModule("userPassword");
			log.setOperateType("resetPassword");
			Long createLongTime = ((new Date().getTime()) / 1000);
			log.setCreatedAt(createLongTime.intValue());
			log.setDescription("重置密码短信发送:用户手机号码"+mobile+"。短信发送返回信息:"+resultInfo);
			operationLogMapper.insert(log);
			
			if (!"短信发送成功".equals(resultInfo)) {
				return false;
			}
			return saveVerifyCode(mobile,code,smsType,userId);
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("发送短信记录异常：",e);
			return false;
		}
		
	}

	@Override
	public boolean sendNumberVerifyCodeSms(String mobile, String type, String userId) {
		try {
			SMSVerifyCode sms = new SMSVerifyCode(mobile);
			sms.setCode(RandomUtil.getRandomNumber(6));
			boolean b = false;
			switch (type) {
				case "2"://找回登录密码
					b = smsService.verifyCodePwd(sms, VerifyCodeType.login_pwd_back) == 1;
					break;
				case "3"://设置支付密码
					b = smsService.verifyCodePwd(sms, VerifyCodeType.pay_pwd_set) == 1;
					break;
				case "4"://找回支付密码
					b = smsService.verifyCodePwd(sms, VerifyCodeType.pay_pwd_back) == 1;
					break;
				case "5"://设置登录密码
					b = smsService.verifyCodePwd(sms, VerifyCodeType.login_pwd_set) == 1;
					break;

				default:
					break;
			}

			OperationLog log = new OperationLog();
			log.setObjId(Integer.parseInt(userId));
			log.setObjName(userId);
			log.setModule("userPassword");
			log.setOperateType("resetPassword");
			Long createLongTime = ((new Date().getTime()) / 1000);
			log.setCreatedAt(createLongTime.intValue());
			log.setDescription("重置密码短信发送:用户手机号码" + mobile + "。短信发送返回信息:" + b);
			operationLogMapper.insert(log);

			if (b) {
				return saveVerifyCode(mobile, sms.getCode(), NumberUtils.toInt(type), userId);
			}
		} catch (Exception e) {
			logger.error("发送短信记录异常：", e);
		}
		return false;

	}
    
	
}
